package club.pinea.handler.lobby;

import club.pinea.annotations.Head;
import club.pinea.interfaces.TCPMessage;
import club.pinea.model.Seat;
import club.pinea.proto.BasicProto;
import club.pinea.proto.CommandProto;
import club.pinea.proto.LobbyProto;
import club.pinea.send.MessageSend;
import club.pinea.service.SeatService;
import club.pinea.service.UserService;
import club.pinea.session.GlobalServerPlayerContainer;
import club.pinea.session.IOSession;
import club.pinea.session.ServerPlayer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @description: 坐到选择的座位 相关代码操作
 * @author: 华上进
 * @createTime: 2021/6/28 10:40
 */
@Head(CommandProto.Command.C_S_SEAT_VALUE)
@Component
public class SeatDownHandler implements TCPMessage<BasicProto.BaseMessage> {
    /**
     * redis座位操作服务类
     */
    @Autowired
    private SeatService seatService;

    /**
     * 用户操作服务类
     */
    @Autowired
    private UserService userService;

    @Value("${server.game.port}")
    public Integer gamePort;

    @Value("${server.game.minScore}")
    public Integer minScore;

    @Value("${server.game.maxScore}")
    public Integer maxScore;

    /**
     * @description: 客户端发送坐下请求，这里接收处理
     * @author: 华上进
     * @createTime: 2021/6/28 13:44
     */
    @Override
    public void doMessage(BasicProto.BaseMessage msg, IOSession session) throws Exception {
        // 接收坐下相关request传入相关代码
        LobbyProto.SeatDownRequest seatDownRequest = LobbyProto.SeatDownRequest.parseFrom(msg.getBody());
        ServerPlayer serverPlayer = GlobalServerPlayerContainer.getServerPlayer(session);
        // 获取userId 存入实体对象，下面逻辑会用到
        // 座位号
        int seatNum = seatDownRequest.getSeatNum();
        // 根据座位号查询 座位实体
        Seat seat = seatService.getSeatBean(seatNum, serverPlayer.getRoom());
        boolean seatLogic = false;
        if (seat == null) {
            throw new IllegalArgumentException("参数错误，没有找到该座位信息：id-" + seatNum);
        }
        if (seat.getSeatStatus() == 2 && seatNum == seat.getSeatId()) {
            throw new IllegalArgumentException("参数错误，您不能进入其他用户正在留机的座位哦！");
        }

        //如果当前座位没人坐，则将座位状态改变并进入座位
        if (!checkSeated(seat)) {
            // 更新座位信息，更新成功返回true
            seatLogic = seatDown(seat, serverPlayer);
        }
        LobbyProto.SeatDownResponse seatDownResponse = null;
        if (seatLogic) {
            serverPlayer.setSeatId(seatDownRequest.getSeatNum());
            seatDownResponse = LobbyProto.SeatDownResponse.newBuilder()
                    .setRes(MessageSend.successRes())
                    .setMaxScore(maxScore)
                    .setMinScore(minScore)
                    .addAllBonus(
                            CollectionUtils.arrayToList(seatService.selPoolScores(seat.getSeatId(), seatDownRequest.getRoomId()))
                    ).build();
        } else {
            List<Seat> roomSeatDownList = seatService.getRoomSeatDownSeatsByKey(serverPlayer.getRoom());
            List<LobbyProto.Seat> seats = new ArrayList<>(roomSeatDownList.size());
            roomSeatDownList.forEach(s -> {
                LobbyProto.Seat.Builder seatFor = LobbyProto.Seat.newBuilder()
                        .setSeatId(s.getSeatId())
                        .setSeatStatus(s.getSeatStatus())
                        .setDate(s.getDate());
                if (s.getSeatUser() != null) {
                    seatFor.setSeatUser(s.getSeatUser());
                }
                seats.add(seatFor.build());
            });
            seatDownResponse = LobbyProto.SeatDownResponse.newBuilder()
                    .setRes(MessageSend.errorRes())
                    .addAllSeats(seats).build();
        }
        MessageSend.sendToUser(seatDownResponse, session);
    }

    /**
     * 判断是否当前座位已有人坐
     *
     * @param seat 通过传入的座位号获取的座位信息
     * @return true 有人坐 false 没人坐
     */
    private boolean checkSeated(Seat seat) {
        return seat.getSeatStatus() == 1 && seat.getSeatUser() != null;
    }

    /**
     * 进入座位改变座位当前状态 将当前座位状态改变，并将当前座位的用户名称设置
     *
     * @param seat 通过传入的座位号获取的座位信息
     * @return true 状态改变成功 false 状态改变失败
     */
    private boolean seatDown(Seat seat, ServerPlayer serverPlayer) {
        seat.setSeatStatus(1);
        String userName = userService.getUserName(serverPlayer.getUserId());
        seat.setSeatUser(userName);
        seatService.updateSeat(seat, seat.getSeatId(), false, serverPlayer.getRoom());
        return seat.getSeatStatus() == 1 && seat.getSeatUser() != null;
    }
}
